package com.yuke.cloud.service.omc.service.impl;

import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.HttpAesUtil;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.cmc.dto.CmsSysInfoDto;
import com.yuke.cloud.service.api.cmc.service.CmcFeignApi;
import com.yuke.cloud.service.api.uac.dto.UserInfoDto;
import com.yuke.cloud.service.api.uac.service.UacUserFeignApi;
import com.yuke.cloud.service.omc.dao.OdsPointsMapper;
import com.yuke.cloud.service.omc.dao.OdsUserPointMapper;
import com.yuke.cloud.service.omc.dto.OdsPointsDto;
import com.yuke.cloud.service.omc.dto.OrderBasicDto;
import com.yuke.cloud.service.omc.dto.OrderInfoDto;
import com.yuke.cloud.service.omc.entity.OdsPoints;
import com.yuke.cloud.service.omc.entity.OdsUserPoint;
import com.yuke.cloud.service.omc.service.OdsPointsService;
import com.yuke.cloud.service.omc.service.OdsUserPointService;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;


/**
 * Created by zn on 2019/12/25.
 */
@Slf4j
@Service
@Transactional
public class OdsPointsServiceImpl extends BaseService<OdsPoints> implements OdsPointsService {
    @Resource
    private OdsPointsMapper odsPointsMapper;
    @Resource
    private OdsUserPointMapper odsUserPointMapper;
    @Resource
    private CmcFeignApi cmcFeignApi;
    @Resource
    private UacUserFeignApi uacUserFeignApi;
    @Resource
    private OdsUserPointService odsUserPointService;

    @Override
    public OdsPoints selectLastOneByUserId(Long userId) {
        return odsPointsMapper.selectLastOneByUserId(userId);
    }

    @Synchronized
    @Override
    public Long doPointUpdate(OdsPointsDto odsPointsDto) {
        //1.查找ods_user_point表，取出point_balance值
        OdsUserPoint odsUserPoint = new OdsUserPoint();
        odsUserPoint.setUserId(odsPointsDto.getUserId());
        List<OdsUserPoint> odsUserPointList = odsUserPointMapper.select(odsUserPoint);

        Integer pointBalance = 0;
        if (odsUserPointList != null && odsUserPointList.size() > 0) {
            pointBalance = Integer.valueOf(HttpAesUtil.decode(odsUserPointList.get(0).getPointBalance()));
        }

        //2.比较取出point_balance值，插入记录
        if (!pointBalance.equals(odsPointsDto.getPointBalance())) {
            log.error("警告：积分表余额与用户积分余额不一致！");
            // throw new BusinessException(ErrorCodeEnum.OMC10031018);
            pointBalance = odsPointsDto.getPointBalance();
        }

        //3.换算积分
        String userPointBalance;
        OdsPoints odsPoints = new OdsPoints();
        BeanUtils.copyProperties(odsPointsDto, odsPoints);
        //非积分购物，充值，number接收的是 金额（分），必须转换成积分
        if (odsPoints.getPointType().toString().equals("1") || odsPoints.getPointType().toString().equals("4")){
            Long groupId = 220839532667469824L;
            Wrapper<UserInfoDto> userInfoDto = uacUserFeignApi.getUserInfoByUserId(odsPointsDto.getUserId());
            if (PublicUtil.isNotEmpty(userInfoDto) && PublicUtil.isNotEmpty(userInfoDto.getResult())){
                groupId = userInfoDto.getResult().getGroupId();
            }

            CmsSysInfoDto cmsSysInfoDto = cmcFeignApi.getSysInfoDtoByType(groupId,GlobalConstant.SysInfo.SYS_INFO_POINT_REBATE);
            String pointRate = "0.01";
             if (PublicUtil.isNotEmpty(cmsSysInfoDto)){
                 pointRate =   cmsSysInfoDto.getInfoValue();
             }
            odsPoints.setNumber(Math.round(odsPoints.getNumber() * Float.valueOf(pointRate)));
        }


        //4.保存ods_points表
        if (odsPointsDto.getPointType().toString().equals("0")) {
            //消费积分
            if (pointBalance > odsPointsDto.getNumber()) {
                pointBalance = pointBalance - odsPoints.getNumber();

            } else {
                return 0L;
            }

        }else if (odsPointsDto.getPointType().toString().equals("8")) {
            //取消订单减分，必须保证取消订单后传过来的是积分
            if (pointBalance > odsPointsDto.getNumber()) {
                pointBalance = pointBalance - odsPoints.getNumber();

            } else {
                pointBalance = 0;
            }

        } else { //添加积分 消费积分，充值积分 一元一分
            //签到积分,奖券积分直接加，积分支付订单取消后返还
            pointBalance =odsPoints.getNumber()  +pointBalance;

        }


        odsPoints.setPointBalance(pointBalance);
        this.save(odsPoints);
        //4.更新ods_user_point表point_balance值
        userPointBalance = HttpAesUtil.encode(pointBalance.toString());
        odsUserPoint.setUserPointId(odsUserPointList.get(0).getUserPointId());
        odsUserPoint.setPointBalance(userPointBalance);
        Integer num = odsUserPointMapper.updateByPrimaryKeySelective(odsUserPoint);

        if (num > 0) {
            return odsUserPoint.getUserId();
        }

        return 0L;
    }

    @Override
    public List<OdsPointsDto> findPoints(OdsPointsDto odsPointsDto) {
        List<OdsPointsDto> points = odsPointsMapper.findPoints(odsPointsDto);
        return points;
    }

    @Override
    public Map<String, Object> getSignInInfo(OdsPointsDto odsPointsDto) {
        //获得7天内的签到信息，中间可能有间断
        Example example = new Example(OdsPoints.class);
        Example.Criteria criteria = example.createCriteria();
        example.setOrderByClause("create_time desc");
        criteria.andEqualTo("userId", odsPointsDto.getUserId());
        criteria.andEqualTo("pointType", 2);
        criteria.andEqualTo("pointAspect", 1);
        criteria.andEqualTo("pointStatus", 0);
        Date date = new Date();
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.add(5, -8);
        Date time = instance.getTime();
        criteria.andGreaterThanOrEqualTo("createTime", time); //7天
        List<OdsPoints> list = odsPointsMapper.selectByExample(example);
        System.out.println("计算连续天数:" + list);
        //计算连续天数
        int continuousDay = 1;
        boolean todaySignIn = false;
        Date today = new Date();
        for (OdsPoints item : list) {
            int intervalDay = (int) ((today.getTime() - item.getCreateTime().getTime()) / (1000 * 60 * 60 * 24));
            //当天签到
            if (intervalDay == 0) {
                todaySignIn = true;
            } else if (intervalDay == continuousDay) {
                continuousDay++;
            } else {
                //不连续，终止判断
                break;
            }

        }
        if (!todaySignIn) {
            continuousDay--;
            //今天未签到，满7天归零
            if (continuousDay > 6) {
                continuousDay = 0;
                //把结算的签到积分标记1
                doPointStatus(odsPointsDto);
            }
        }


        Map<String, Object> map = new HashMap<>();
        map.put("continuousDay", continuousDay);

        Long groupId = 220839532667469824L;
        Wrapper<UserInfoDto> userInfoDto = uacUserFeignApi.getUserInfoByUserId(odsPointsDto.getUserId());
        if (PublicUtil.isNotEmpty(userInfoDto) && PublicUtil.isNotEmpty(userInfoDto.getResult())){
            if (userInfoDto.getResult().getGroupId() != null && userInfoDto.getResult().getGroupId() > 0){
                groupId = userInfoDto.getResult().getGroupId();
            }

        }
        CmsSysInfoDto cmsSysInfoDto = cmcFeignApi.getSysInfoDtoByType(groupId,GlobalConstant.SysInfo.SYS_INFO_POINT_SIGNIN);
        String pointSignIn = cmsSysInfoDto.getInfoValue();

        map.put("pointSignIn", pointSignIn);

        return map;
    }

    @Override
    public Integer setOdsPoint(OrderInfoDto orderInfoDto) {
        //获取所有商品积分
        //定义商品积分
        Integer pointGoodsBalance = 0;
        List<OrderBasicDto> orderBasicDtos = orderInfoDto.getOrderBasicDtos();
        OrderBasicDto orderBasicDto = orderBasicDtos.get(0);
        pointGoodsBalance = orderBasicDto.getPointBalance();
        //获取商品积分
        //pointGoods = orderGoodsDtos.stream().collect(Collectors.summingInt(OrderGoodsDto::getPointBalance));

        //获取订单类型
        Byte orderType = orderBasicDtos.get(0).getOrderType();

        OdsUserPoint userPoint1 = new OdsUserPoint();
        userPoint1.setUserId(orderInfoDto.getUserId());

        Example example = new Example(OdsUserPoint.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", orderInfoDto.getUserId());
        List<OdsUserPoint> odsUserPoints = odsUserPointService.selectByExample(example);


        OdsUserPoint userPoint = odsUserPointService.findById(odsUserPoints.get(0).getUserPointId());

        //积分解密
        //System.out.println("pointBalance :" + odsUserPoints.getPointBalance());
        String pointBalance = userPoint.getPointBalance();
        String decode = HttpAesUtil.decode(pointBalance);

        Integer user = Integer.parseInt(decode);

        if (user < pointGoodsBalance) {
            log.error("当前积分不足");
        }
        //定义使用过后的积分
        Integer s = 0;
        s = user - pointGoodsBalance;
        OdsUserPoint odsUserPoint = new OdsUserPoint();
        odsUserPoint.setUserPointId(userPoint.getUserPointId());
        //加密保存
        String encode = HttpAesUtil.encode(s.toString());
        odsUserPoint.setPointBalance(encode);
        odsUserPointService.update(odsUserPoint);

        //添加一条积分消费记录
        OdsPoints odsPoints = new OdsPoints();
        odsPoints.setPointId(generateId());
        odsPoints.setUserId(userPoint.getUserId());

        odsPoints.setNumber(pointGoodsBalance);
        odsPoints.setPointType((byte) 0);
        odsPoints.setPointBalance(s);
        odsPoints.setPointStatus((byte) 0);
        if (orderType.toString().equals("1")) {
            odsPoints.setPointAspect((byte) 1);
        } else {
            odsPoints.setPointAspect((byte) 2);
        }
        Integer save = save(odsPoints);

        return save;
    }

    private void doPointStatus(OdsPointsDto odsPointsDto) {
        OdsPoints odsPoints = new OdsPoints();
        odsPoints.setUserId(odsPointsDto.getUserId());
        Date date = new Date();
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.add(5, -8);
        Date time = instance.getTime();
        odsPoints.setCreateTime(time);
        odsPoints.setPointType((byte) 2);
        odsPoints.setPointAspect((byte) 1);
        odsPointsMapper.updatePointStatus(odsPoints);
    }
}
